﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Kooboo.IoC;
using Kooboo.Domain;
using Kooboo.Collections;

using Kooboo.Commerce.Contexts.Carts;

namespace Kooboo.Commerce.Contexts.Products
{
    public static class EditorBehavior
    {
        #region Product

        public static void Post(this IEditor actor, IProduct product, List<ICategory> categoires)
        {
            
            using (var transaction = ObjectContainer.CreateInstance<TransactionContext>())
            {
                try
                {
                    var repository = ContextContainer.Current.Resolve<IProductRepository>();
                    repository.Post(product);

                  

                    if (categoires != null)
                    {
                        foreach (var i in categoires)
                        {
                            i.Include(product);
                        }
                    }

                    transaction.Commit();
                }
                catch
                {
                    transaction.Rollback();
                    throw;
                }
            }

        }

        public static void Put(this IEditor actor, IProduct product, List<ICategory> categoires, bool hasTransaction = false)
        {

            using (var transaction = ObjectContainer.CreateInstance<TransactionContext>())
            {
                try
                {
                    var repository = ContextContainer.Current.Resolve<IProductRepository>();
                    repository.Put(product);

                    if (categoires != null)
                    {
                        var list = product.Categories.Compare(categoires, (i1, i2) => i1.Id == i2.Id, null);

                        foreach (var i in list.Added)
                        {
                            i.Include(product);
                        }

                        foreach (var i in list.Deleted)
                        {
                            i.Exclude(product);
                        }
                    }

                    transaction.Commit();
                }
                catch
                {
                    transaction.Rollback();
                    throw;
                }
            }

        }

        public static void Delete(this IEditor actor, IProduct product, bool hasTransaction = false)
        {

            using (var transaction = ObjectContainer.CreateInstance<TransactionContext>())
            {
                try
                {
                    var item = actor.QueryProducts().Where(i => i.Id == product.Id).FirstOrDefault();

                    //delete cart item
                    actor.QueryCartItems().Where(i => i.Product.Id == item.Id)
                        .ToDelete().Execute();
                   

                    foreach (var c in item.Categories)
                    {
                        c.Exclude(item);
                    }

                    foreach (var question in item.ProductQuestions)
                    {
                        actor.Delete(question);
                    }
                  
                    foreach (var review in item.ProductReviews)
                    {
                        actor.Delete(review);
                    }

                    item.ProductCustomFields
                        .ToDelete()
                        .Execute();

                    item.SaleItems
                        .SelectMany(i => i.ProductVariations)
                        .ToDelete()
                        .Execute();

                    item.SaleItems
                        .ToDelete()
                        .Execute();

                    item.ProductImages
                        .ToDelete()
                        .Execute();

                    //foreach (var i in item.Orders)
                    //{
                    //    actor.Delete(i);
                    //}

                    var repository = ContextContainer.Current.Resolve<IProductRepository>();
                    repository.Delete(item);

                    transaction.Commit();
                }
                catch
                {
                    transaction.Rollback();
                    throw;
                }
            }

        } 

        #endregion

        #region ProductQuetion
        public static void Post(this IEditor actor, IProductQuestion productQuestion)
        {

            using (var transaction = ObjectContainer.CreateInstance<TransactionContext>())
            {
                try
                {
                    var repository = ContextContainer.Current.Resolve<IProductQuestionRepository>();
                    repository.Post(productQuestion);

                    transaction.Commit();
                }
                catch
                {
                    transaction.Rollback();
                    throw;
                }
            }

        }

        public static void Put(this IEditor actor, IProductQuestion productQuestion)
        {


            using (var transaction = ObjectContainer.CreateInstance<TransactionContext>())
            {
                try
                {
                    var repository = ContextContainer.Current.Resolve<IProductQuestionRepository>();
                    repository.Put(productQuestion);

                    transaction.Commit();
                }
                catch
                {
                    transaction.Rollback();
                    throw;
                }
            }

        }

        public static void Delete(this IEditor actor, IProductQuestion productQuestion)
        {

            using (var transaction = ObjectContainer.CreateInstance<TransactionContext>())
            {
                try
                {
                    var repository = ContextContainer.Current.Resolve<IProductQuestionRepository>();
                    repository.Delete(productQuestion);

                    transaction.Commit();
                }
                catch
                {
                    transaction.Rollback();
                    throw;
                }
            }

        } 
        #endregion

        #region ProductReview
        public static void Post(this IEditor actor, IProductReview review)
        {

            using (var transaction = ObjectContainer.CreateInstance<TransactionContext>())
            {
                try
                {
                    var repository = ContextContainer.Current.Resolve<IProductReviewRepository>();
                    repository.Post(review);

                    transaction.Commit();
                }
                catch
                {
                    transaction.Rollback();
                    throw;
                }
            }
        }


        public static void Put(this IEditor actor, IProductReview review)
        {

            using (var transaction = ObjectContainer.CreateInstance<TransactionContext>())
            {
                try
                {
                    var repository = ContextContainer.Current.Resolve<IProductReviewRepository>();
                    repository.Put(review);

                    transaction.Commit();
                }
                catch
                {
                    transaction.Rollback();
                    throw;
                }
            }
        }

        public static void Delete(this IEditor actor, IProductReview review)
        {

            using (var transaction = ObjectContainer.CreateInstance<TransactionContext>())
            {
                try
                {
                    var repository = ContextContainer.Current.Resolve<IProductReviewRepository>();
                    repository.Delete(review);

                    transaction.Commit();
                }
                catch
                {
                    transaction.Rollback();
                    throw;
                }
            }
        }
        #endregion
    }
}
